﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CSequence;
using Ini;
using System.Security.Cryptography;
using System.Data.Common;

namespace Sequence
{
    public partial class MDISequence : Form
    {
        private int childFormNumber = 0;
        public CWikiSourceControl oWikiSourceControl = null;

        public DbConnection m_connection = null;
        private DbProviderFactory m_oDbProviderFactory = null;
        private string m_sConnectionType = "";

        private IniFile oIni = null;

        public MDISequence()
        {
            InitializeComponent();
            oIni = new IniFile("C:\\Sapiens\\Sequence\\Sequence.ini");
        }

        public void RunCommand(string[] arg)
        {            
            FrmSequence2 oFrmSequence2 = new FrmSequence2();
            oFrmSequence2.MdiParent = this;
  
            // Command line example RunBatch batchId=51 Next=123
            if (arg.Length >= 2)
            {
                oFrmSequence2.OpenByName(arg[0]);
                for (int i = 1; i < arg.Length; i++)
                {
                   oFrmSequence2.SetParam( arg[i]) ;
                }
                oFrmSequence2.RunSequence();
            }
        }

        private DbConnection GetConntion()
        {
            return m_connection;
        }

        class CMyOracleConnectionStringBuilder
        {
            public CMyOracleConnectionStringBuilder()
            {
                InitVars();
                m_ConnectionString = "";
            }
            public CMyOracleConnectionStringBuilder(string sConn)
            {
                InitVars();
                ConnectionString = sConn;
            }
           
            public void InitVars()
            {
                UserID = "";
                Provider = "";
                DataSource = "";
                Password = "";
            }

            private string m_ConnectionString;
            public string UserID, Provider, DataSource, Password;
            public string  ConnectionString
            {
                get
                {
                    return this.m_ConnectionString;
                }
                set
                {
                    this.m_ConnectionString = value;
                    // Example Provider=OraOLEDB.Oracle;Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=Localhost)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME = ALISDB)(SERVER=DEDICATED)));User Id=ALIS;Password=oracle;
                    string[] sPairs = m_ConnectionString.Split(';');
                    foreach ( string sPair in sPairs)
                    {
                        string[] sPairParts = sPair.Split('=');
                        if (sPairParts.Count() >= 2)
                        {
                            switch (sPairParts[0].ToLower() )   
                            {
                                case "provider":
                                    Provider = sPairParts[1];
                                    break;
                                case "data source":
                                    DataSource = sPair.Replace("Data Source=","");
                                    break;
                                case "user id":
                                    UserID = sPairParts[1];
                                    break;
                                case "password":
                                    Password = sPairParts[1];
                                    break;
                            }
                        }
                    }
                }
            }
        }

        class CEncryptor
        {

            private static byte[] key = new byte[8] { 1, 2, 3, 4, 5, 6, 7, 8 };
            private static byte[] iv = new byte[8] { 1, 2, 3, 4, 5, 6, 7, 8 };

            public  string Crypt(string text)
            {
                string sRet = "";
                if (text.Length > 0)
                {
                    SymmetricAlgorithm algorithm = DES.Create();
                    ICryptoTransform transform = algorithm.CreateEncryptor(key, iv);
                    byte[] inputbuffer = Encoding.Unicode.GetBytes(text);
                    byte[] outputBuffer = transform.TransformFinalBlock(inputbuffer, 0, inputbuffer.Length);
                    sRet = Convert.ToBase64String(outputBuffer);
                }
                return sRet;

            }

            public  string Decrypt(string text)
            {
                string sRet = "";
                if (text.Length > 0)
                {
                    SymmetricAlgorithm algorithm = DES.Create();
                    ICryptoTransform transform = algorithm.CreateDecryptor(key, iv);
                    byte[] inputbuffer = Convert.FromBase64String(text);
                    byte[] outputBuffer = transform.TransformFinalBlock(inputbuffer, 0, inputbuffer.Length);
                    sRet = Encoding.Unicode.GetString(outputBuffer);
                }
                return sRet;
            }
        }

        public CWikiSourceControl GetWiki()
        {
            return oWikiSourceControl;
        }

        public string GetConnectionType()
        {
            if ( m_sConnectionType == "")
                 m_sConnectionType = CSqlString.GetConnectionType(GetConntion().ConnectionString);

            return m_sConnectionType;
        }

       

        public DbConnection GetConnection()
        {
            String sConn = GetConnectString();
            if (m_connection == null)
            {
                try
                {                                        
                    m_connection = m_oDbProviderFactory.CreateConnection();
                    m_connection.ConnectionString = sConn;
                    m_connection.Open();
                    if (m_connection.State == ConnectionState.Closed)
                        m_connection = null;

                }
                catch (Exception ex)
                {
                    m_connection = null;
                    DialogResult dialogResult = MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
            return m_connection;
        }

        public String GetConnectString()
        {

            // Typically "System.Data.SqlClient" or "System.Data.OracleClient"
            string sProviderFactories = oIni.IniReadValue("Settings", "ProviderFactories", "System.Data.OracleClient");
            m_oDbProviderFactory = DbProviderFactories.GetFactory(sProviderFactories);

            String sGetConnectString = oIni.IniReadValue("Settings", "ConnectString", "Provider=OraOLEDB.Oracle;Data Source=uslt023;User ID=ALIS;Password=oracle;");
            return sGetConnectString;
        }

        void OpenRecentFile(object sender, EventArgs e)
        {
            var menuItem = (ToolStripMenuItem)sender;
            var filepath = (string)menuItem.Tag;
            
            FrmSequence2 childForm = new FrmSequence2();
            childForm.MdiParent = this;
            //childForm.Text = "Sequence " + childFormNumber++;
            //childForm.Path = filepath;
            childForm.Show();
        }

        private void ShowNewForm(object sender, EventArgs e)
        {

            RunSql("insert into t_api_qd_process (ID, NAME) values ( (select nvl(max(id),0)+1 from t_api_qd_process ), 'New')");
            FrmSequence2 childForm = new FrmSequence2();
            childForm.MdiParent = this;
            childForm.Text = "Sequence " + childFormNumber++;
            childForm.sId = GetMaxProcess();
            childForm.Show();
               
        }
        
        private string GetMaxProcess()
        {

            string sSql = "select nvl(max(id),0) from t_api_qd_process";
            string sRet = "";
            try
            {
                DbCommand command = GetConntion().CreateCommand();
                command.CommandText = sSql;
                command.CommandType = CommandType.Text;
                DbDataReader oDataReader = command.ExecuteReader();
            
                while (oDataReader.Read())
                {
                    sRet = oDataReader[0].ToString();
                }
                oDataReader.Close();
                oDataReader.Dispose();
                command.Dispose();

            }
            catch (Exception ex)
            {
                DialogResult dialogResult = MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
            return sRet;
        }

        private bool RunSql(String sSql)
        {
            bool bRet = true;
            try
            {                
                DbCommand command = GetConntion().CreateCommand();
                command.CommandText = sSql;
                command.CommandType = CommandType.Text;

                int iRows = command.ExecuteNonQuery();
                command.Dispose();
            }
            catch (Exception ex)
            {
                DialogResult dialogResult = MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                bRet = false;
            }
            return bRet;
        }

        private void OpenFile(object sender, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            DialogResult result = fbd.ShowDialog();


            if (result == DialogResult.OK)
            {

                String sMRUPath = fbd.SelectedPath;
                for (int i = 1; i < 100; i++)
                {
                    string sIniMRUPath = oIni.IniReadValue("MRU", "Path" + i.ToString());
                    if (sIniMRUPath == "")
                    {
                        oIni.IniWriteValue("MRU", "Path" + i.ToString(), sMRUPath);
                        break;
                    }
                    else if (sMRUPath == sIniMRUPath)
                        break;
                }
                
                FrmSequence2 childForm = new FrmSequence2();
                childForm.MdiParent = this;
                childForm.Text = "Sequence " + childFormNumber++;
                //childForm.Path = fbd.SelectedPath;
                childForm.Show();
            }
        }

        private void SaveAsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog = new SaveFileDialog();
            saveFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
            saveFileDialog.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
            if (saveFileDialog.ShowDialog(this) == DialogResult.OK)
            {
                string FileName = saveFileDialog.FileName;
            }
        }

        private void ExitToolsStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void CutToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void CopyToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void PasteToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void ToolBarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            toolStrip.Visible = toolBarToolStripMenuItem.Checked;
        }

        private void StatusBarToolStripMenuItem_Click(object sender, EventArgs e)
        {
            statusStrip.Visible = statusBarToolStripMenuItem.Checked;
        }

        private void CascadeToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.Cascade);
        }

        private void TileVerticalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.TileVertical);
        }

        private void TileHorizontalToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.TileHorizontal);
        }

        private void ArrangeIconsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            LayoutMdi(MdiLayout.ArrangeIcons);
        }

        private void CloseAllToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (Form childForm in MdiChildren)
            {
                childForm.Close();
            }
        }

        private void MDISequence_Load(object sender, EventArgs e)
        {
            this.WindowState = FormWindowState.Maximized;
        }

        private void toolStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            foreach (FrmSequence2 childForm in MdiChildren)
            {
                childForm.Save();
            }
        }

        private void recentFoldersToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void saveToolStripButton_Click(object sender, EventArgs e)
        {
            foreach (FrmSequence2 childForm in MdiChildren)
            {
                childForm.Save();
            }
        }

        private void openDBToolStripMenuItem_Click(object sender, EventArgs e)
        {
            CMyOracleConnectionStringBuilder builder = new CMyOracleConnectionStringBuilder(GetConnectString());                
            DbConnection oConnection = GetConnection();
            if (oConnection.State != ConnectionState.Open)
            {                
                tsslMain.Text ="Failed to connect to (" + builder.UserID + ")";
            }
            else
            {
                tsslMain.Text = "Connect to (" + builder.UserID + ")";
                FrmOpenProcess oFrmOpenProcess = new FrmOpenProcess(oConnection);
                oFrmOpenProcess.Init();
                oFrmOpenProcess.ShowDialog();

                if (oFrmOpenProcess.sId != null)
                {
                    if (oFrmOpenProcess.sId != "")
                    {
                        OpenProcess(oFrmOpenProcess.sId);
                    }
                }
            }
        }

        public void OpenProcess(string sId)
        {
            FrmSequence2 childForm = new FrmSequence2();
            childForm.MdiParent = this;
            childForm.Text = "Sequence " + childFormNumber++;
            childForm.SourceControl(tsslSourceCon.Text);
            childForm.sId = sId;
            childForm.Show();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            timer1.Enabled = false;
            DbCommand command = GetConnection().CreateCommand();
            if (oIni.IniReadValue("Wiki", "Enabled", "No") == "Yes")
            {
                string sUser = "Unknown";
                CEncryptor oEncryptor = new CEncryptor();
                string[] sNames = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\');
                if (sNames.Count() == 2)
                    sUser = sNames[1];
                string sTemp = oEncryptor.Crypt("9TheParade");

                String sGetConnectString = oIni.IniReadValue("Settings", "ConnectString");
                if (oWikiSourceControl == null)
                    oWikiSourceControl = new CWikiSourceControl();

                oWikiSourceControl.Connect(oIni.IniReadValue("Wiki", "Path", "http://ukdt198.sapiens.int/mediawiki"),
                                           oIni.IniReadValue("Wiki", "User", sUser),
                                           oEncryptor.Decrypt(oIni.IniReadValue("Wiki", "Password", oEncryptor.Crypt("Pa55word"))),
                                           oIni.IniReadValue("Wiki", "Library", "Sequence"));
                if (oWikiSourceControl.bConnected)
                    tsslSourceCon.Text = "SC:Connected";
                else
                {
                    tsslSourceCon.Text = "SC:Disconnected";
                    oWikiSourceControl = null;
                }
            }
        }

        private void keep(object sender, EventArgs e)
        {
        }

        private void tsslSourceCon_Click(object sender, EventArgs e)
        {

        }

        private void tsslSourceCon_DoubleClick(object sender, EventArgs e)
        {
            
                 
        }

        private void connectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Cursor.Current = Cursors.WaitCursor;
            if (tsslSourceCon.Text == "SC:Disconnected")
            {

                string sUser = "Unknown";
                CEncryptor oEncryptor = new CEncryptor();
                string[] sNames = System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split('\\');
                if (sNames.Count() == 2)
                    sUser = sNames[1];
                
                if (oWikiSourceControl == null)
                    oWikiSourceControl = new CWikiSourceControl();

                if (oWikiSourceControl.Connect(oIni.IniReadValue("Wiki", "Path", "http://ukdt198.sapiens.int/mediawiki"),
                                           oIni.IniReadValue("Wiki", "User", sUser),
                                           oEncryptor.Decrypt(oIni.IniReadValue("Wiki", "Password", oEncryptor.Crypt("Pa55word"))),
                                           oIni.IniReadValue("Wiki", "Library", "Sequence")))
                {
                    tsslSourceCon.Text = "SC:Connected";
                }
                else
                {
                    MessageBox.Show(oWikiSourceControl.sLastError, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    oWikiSourceControl = null;
                }
                Cursor.Current = Cursors.Default;
            }
        }

        private void disconnectToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tsslSourceCon.Text == "SC:Connected")
            {
                oWikiSourceControl.DisConnect();
                oWikiSourceControl = null;
                tsslSourceCon.Text = "SC:Disconnected";
            }      
        }

        private void WriteError(string sErr)
        {
             MessageBox.Show(sErr, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        private void rebaseFromMasterToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (tsslSourceCon.Text == "SC:Disconnected")
                WriteError("Disconnected from Source control !!");
            else
            {
                DialogResult dialogResult = MessageBox.Show("This will rebase your database from the master\r\nAll your changes not checked in will be lost\r\nand this may take a lone time to run\r\n\r\nAre you sure you want to continue ", "Source control", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                if (dialogResult == DialogResult.Yes)
                {
                    RunSql("delete from T_API_QD_PROCESS");
                    RunSql("delete from T_API_QD_PROCESS_STEP");
                    RunSql("delete from T_API_QD_PROCESS_STEP_PARAMS");

                    oWikiSourceControl.GetSCStatus();
                    List<CWikiSourceControl.CSCStatus> listCSCStatus = oWikiSourceControl.listCSCStatus;
                    foreach (CWikiSourceControl.CSCStatus oCSCStatus in listCSCStatus)
                    {
                        tsslMain.Text = "Adding Row-" + oCSCStatus.sRowTypeId;
                        string sMaster = oWikiSourceControl.GetText(oCSCStatus.sName);
                        //int lStart = sMaster.IndexOf("<Pre>");
                        /*if (sMaster.IndexOf("--Export Metadata for ID") > 0)
                        {
                            int iPos = sMaster.IndexOf("--Export Metadata for ID");
                            int iPos2 = sMaster.IndexOf("\n", iPos + 1);

                            int iMasterId = Convert.ToInt16(sMaster.Substring(iPos + 24, iPos2 - iPos - 24));
                            if (Convert.ToInt16(oCSCStatus.sRowTypeId) != iMasterId)
                              //  WriteError("** Need to fix  " + oCSCStatus.sName + "(" + oCSCStatus.sRowTypeId + ")-(" + iMasterId.ToString() + ")", true);
                        }*/


                        string sToAddSql = "Begin\r\n" + sMaster.Replace("\n", "\r\n") + "End;\r\n";
                        sToAddSql = sToAddSql.Replace("/r/n", "\r\n");
                        if (RunSql(sToAddSql))
                            WriteError("Added row " + oCSCStatus.sName + "(" + oCSCStatus.sRowTypeId + ") to your database");
                        else
                            WriteError("*Error - Adding row " + oCSCStatus.sName + "(" + oCSCStatus.sRowTypeId + ") to your database");
                        
                    }

                }
            }
        }

        private void optionsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmOptions oOpt = new FrmOptions();
            oOpt.ShowDialog();
        }

        private void serviceUsageToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmServiceUsage oUsage = new FrmServiceUsage(GetConnection());
            oUsage.ShowDialog();
        }
    }
}
